package main

import (
	"fmt"
	"io"
	"reflect"
)

// person 结构体定义了人的基本信息
type person struct {
	Name string
	Age  int
}

// String 实现了 fmt.Stringer 接口，用于生成 person 实例的字符串表示
func (p person) String() string {
	return fmt.Sprintf("the person is %s, age is %d", p.Name, p.Age)
}

func main() {
	// 初始化一个整数变量 i
	i := 3
	// 使用反射获取 i 的值和类型
	iv := reflect.ValueOf(i)
	it := reflect.TypeOf(i)
	fmt.Println(iv, it)

	// 获取原始值
	i1 := iv.Interface().(int)
	fmt.Println(i1)

	// 修改值
	// 获取值的拷贝
	ipv := reflect.ValueOf(&i)
	// 获取值并修改
	ipv.Elem().SetInt(4)
	fmt.Println(i)

	// 初始化一个 person 实例
	p := person{Name: "zhangsan", Age: i1}
	// 使用反射获取 p 的值和类型
	ppv := reflect.ValueOf(&p)
	pv := reflect.ValueOf(p)
	// 通过反射修改 p 的值
	ppv.Elem().Field(0).SetString("lisi")
	ppv.Elem().Field(1).SetInt(20)
	fmt.Println(p)

	// 打印 p 的种类
	fmt.Println(ppv.Kind())
	fmt.Println(pv.Kind())

	// 获取 person 类型的信息
	pt := reflect.TypeOf(p)
	// 遍历 person 的字段
	for i := 0; i < pt.NumField(); i++ {
		fmt.Println("字段：", pt.Field(i).Name)
	}
	// 遍历 person 的方法
	for i := 0; i < pt.NumMethod(); i++ {
		fmt.Println("方法：", pt.Method(i).Name)
	}

	stringerType := reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
	writerType := reflect.TypeOf((*io.Writer)(nil)).Elem()
	fmt.Println("是否实现了fmt.Stringer:", pt.Implements(stringerType))
	fmt.Println("是否实现了io.Writer:", pt.Implements(writerType))
}
